
QFaces.Faces.UICalendar = {
	init : function(debug, ID_CLIENT, ID_INPUT, ID_CONTENT, ID_CONTENT_HEADER, ID_CONTENT_BODY, ID_CONTENT_FOOTER, ID_FRAME, 
			componentClass, listenerExp, 
			href, target, showActionPanel, imgFlagSrc, imgPreviousSrc, imgNextSrc, imgSelectSrc,
			strMonth, strWeek, _for, renderAsPop, pattern, autoClose, startYear, visibleYear, 
			styleClassCalendarBody, styleClassYearSelected,styleClassMonthSelected,styleClassDaySelected,styleClassDayCurrent,styleClassDayOnmouseover,
			styleClassYear,styleClassMonth,styleClassWeek,styleClassDayOfMonth,styleClassActionPanel,styleClassActionDate) {
		var calendar = new QFaces.Faces.UICalendar.Calendar(debug, ID_CLIENT, ID_INPUT, ID_CONTENT, ID_CONTENT_HEADER, ID_CONTENT_BODY, ID_CONTENT_FOOTER, ID_FRAME, 
				componentClass, listenerExp,
				href, target, showActionPanel, imgFlagSrc, imgPreviousSrc, imgNextSrc, imgSelectSrc,
				strMonth, strWeek, _for, renderAsPop, pattern, autoClose, startYear, visibleYear, 
				styleClassCalendarBody, styleClassYearSelected,styleClassMonthSelected,styleClassDaySelected,styleClassDayCurrent,styleClassDayOnmouseover,
				styleClassYear,styleClassMonth,styleClassWeek,styleClassDayOfMonth,styleClassActionPanel,styleClassActionDate);
		QFaces.Faces.put(ID_CLIENT, calendar);
	},
	get : function(ID_CLIENT) {
		return QFaces.Faces.find(ID_CLIENT);
	},
	display : function(ID_CLIENT) {
		QFaces.Faces.find(ID_CLIENT).display();
	}
}
QFaces.Faces.UICalendar.Utils = {
    // 获取指定月份的天数
    getTotalDaysOfMonth : function(year, month) {
        var day = new Date(year, month, 0);
        return day.getDate();
    },
	//获取某月份的第一天是星期几
	getStartDayOfWeek : function(year, month) {
	    var day = new Date(year, month, 1);
	    return day.getDay();
	}
}
QFaces.Faces.UICalendar.Calendar = function(debug, ID_CLIENT, ID_INPUT, ID_CONTENT, ID_CONTENT_HEADER, ID_CONTENT_BODY, ID_CONTENT_FOOTER, ID_FRAME, 
		componentClass, listenerExp,
		href, target, showActionPanel, imgFlagSrc, imgPreviousSrc, imgNextSrc, imgSelectSrc,
		strMonth, strWeek, _for, renderAsPop, pattern, autoClose, startYear, visibleYear, 
		styleClassCalendarBody, styleClassYearSelected,styleClassMonthSelected,styleClassDaySelected,styleClassDayCurrent,styleClassDayOnmouseover,
		styleClassYear,styleClassMonth,styleClassWeek,styleClassDayOfMonth,styleClassActionPanel,styleClassActionDate) {
	this.debug = debug;
	this.clientId = ID_CLIENT;
	this.ID_CLIENT = ID_CLIENT;
	this.input = QFaces.Utils.getElement(ID_INPUT);
	this.content = QFaces.Utils.getElement(ID_CONTENT);
	this.contentHeader = QFaces.Utils.getElement(ID_CONTENT_HEADER);
	this.contentBody = QFaces.Utils.getElement(ID_CONTENT_BODY);
	this.contentFooter = QFaces.Utils.getElement(ID_CONTENT_FOOTER);
	this.frame = QFaces.Utils.getElement(ID_FRAME);
	this.componentClass = componentClass;
	this.listenerExp = listenerExp;
	this.href = href;
	this.target = target;
	this.showActionPanel = (showActionPanel == "true");
	this.imgFlagSrc = imgFlagSrc;
	this.imgPreviousSrc = imgPreviousSrc;
	this.imgNextSrc = imgNextSrc;
	this.imgSelectSrc = imgSelectSrc;
	this.monthArr = strMonth.split(",");
	this.weekArr = strWeek.split(",");
	this._for = (_for != null ? _for.split(",") : null);
	this.renderAsPop = (renderAsPop == "true");
	this.pattern = pattern;
	this.autoClose = (autoClose == "true");
	this.startYear = parseInt(startYear, 10);
	this.visibleYear = parseInt(visibleYear, 10);
	
	this.date; 			// Calendar的日期
	this.objYear;		// 年份区域
	this.objMonth;		// 月份区域
	this.yearPanel;		// 年份选择面板
	this.monthPanel;	// 月份选择面板
	this.actionPanel;	// 日历事件面板
	
	this.styleClassCalendarBody = styleClassCalendarBody;
	this.styleClassYearSelected = styleClassYearSelected;
	this.styleClassMonthSelected = styleClassMonthSelected;
	this.styleClassDaySelected = styleClassDaySelected;
	this.styleClassDayCurrent = styleClassDayCurrent;
	this.styleClassDayOnmouseover = styleClassDayOnmouseover;	// 鼠标放上时，日期的响应样式
	this.styleClassYear = styleClassYear;
	this.styleClassMonth = styleClassMonth;
	this.styleClassWeek = styleClassWeek;
	this.styleClassDayOfMonth = styleClassDayOfMonth;
	this.styleClassActionPanel = styleClassActionPanel;			// 活动事件描述面板的样式
	this.styleClassActionDate = styleClassActionDate;
	
	// ---- Interface
	
	// Interface:获取组件的当前日期
	this.getDate = function() {
		return this.date;
	}
	// Interface:设置组件的当前日期
	// date -> 日期类型, updateTarget -> 是否立即更新目标组件的值
	this.setDate = function(date, updateTarget) {
		QFaces.debug("setDate=" + date);
		this.date = date;
		if (this.renderAsPop) {
			this.updateState(updateTarget);		
		} else {
			this.ajaxInvokeActionDate();
		}
	}
	// Interface:获取格式化后的日期
	this.getValue = function() {
		if (this.date == null) return "";
		return QFaces.DateFormat.format(this.date, this.pattern);
	}
	// Interfaces:显示或关闭日历窗口
	this.display = function() {
		this.frame.style.display == "none" ? this.open() : this.close();
		if (this.isOpen()) {
			var _dd = this.loadDate();
			if (_dd != null) {
				// 如果目标组件的值不为空，则应该在打开的时候让“年份面板“的年份显示到正确的位置,以方便选择
				var currentYear = _dd.getFullYear();
				var startYear = currentYear - parseInt(this.visibleYear / 2, 10);
				this.yearPanel.reload(startYear);
				this.yearPanel.updateState();
			} else {
				_dd = new Date();
			}
			this.setDate(_dd);
		}
	}
	// Interface: 显示日历窗口,同时将calendar窗口设置到鼠标所在位置
	this.open = function() {
		var pos = QFaces.Utils.getMousePosition();
		QFaces.Utils.setPosition(this.frame, pos.x - 10, pos.y + 10);
		QFaces.Utils.open(this.frame);
	}
	// Interface: 关闭日历窗口
	this.close = function() {
		QFaces.Utils.close(this.frame);
		this.yearPanel.close();
		this.monthPanel.close();
	}
	
	// ---- init 
	
	this.init = function() {
		QFaces.setDebug(this.debug);
		var _self = this;
		this.date = new Date();
		this.objYear = document.createElement("span");
		this.objMonth = document.createElement("span");
		this.panelYear = document.createElement("div");
		this.panelMonth = document.createElement("div");
		this.yearPanel = new QFaces.Faces.UICalendar.YearPanel(this);
		this.monthPanel = new QFaces.Faces.UICalendar.MonthPanel(this);
		this.actionPanel = new QFaces.Faces.UICalendar.ActionPanel(this);
		this.renderAll();
		this.updateState();
		if (this.renderAsPop) {
			this.close();
		} else {
			QFaces.debug("Init初始化日历，自动载入数据!");
			QFaces.Utils.setTimeout(_self.ajaxInvokeActionDate, 500, _self);
		}
	}
	this.renderAll = function() {
		this.renderHeader();
		this.renderBody();
		this.renderFooter();
	}
	this.renderHeader = function() {
		var table = document.createElement("table");
		var zoneYear = document.createElement("div");
		var zoneMonth = document.createElement("div");
		var zoneMonthPrevious = document.createElement("div");
		var zoneMonthNext = document.createElement("div");
		
		// zoneYear
		var imgYearSel = document.createElement("img");
		imgYearSel.src = this.imgSelectSrc;
		zoneYear.appendChild(this.objYear);
		zoneYear.appendChild(imgYearSel);
		
		// zoneMonth
		var imgMonthSel = document.createElement("img");
		imgMonthSel.src = this.imgSelectSrc;
		zoneMonth.appendChild(this.objMonth);
		zoneMonth.appendChild(imgMonthSel);
		
		// zoneMonthPrevious
		var imgMonthPrevious = document.createElement("img");
		imgMonthPrevious.setAttribute("src", this.imgPreviousSrc);
		zoneMonthPrevious.appendChild(imgMonthPrevious);
		
		// zoneMonthNext
		var imgMonthNext = document.createElement("img");
		imgMonthNext.src = this.imgNextSrc;
		zoneMonthNext.appendChild(imgMonthNext);
		
		var rows = QFaces.Utils.createTable(table, 1, 4);
		rows[0][0].appendChild(zoneMonthPrevious);
		rows[0][1].appendChild(zoneYear);
		rows[0][1].appendChild(this.yearPanel.getPanel());
		rows[0][2].appendChild(zoneMonth);
		rows[0][2].appendChild(this.monthPanel.getPanel());
		rows[0][3].appendChild(zoneMonthNext);
		
		// event
		var _self = this;
		rows[0][0].style.border = rows[0][3].style.border = "1px solid #FFF";
		rows[0][0].onmouseover = rows[0][3].onmouseover = function() {this.style.border = "1px solid #C0C0C0";}
		rows[0][0].onmouseout = rows[0][3].onmouseout = function() {this.style.border = "1px solid #FFF";}
		
		rows[0][1].style.border = rows[0][2].style.border = "1px solid #F0F0F0";		
		rows[0][1].onmouseover = rows[0][2].onmouseover = function() {this.style.border = "1px solid #C0C0C0";}
		rows[0][1].onmouseout = rows[0][2].onmouseout = function() {this.style.border = "1px solid #F0F0F0";}
		
		rows[0][1].onclick = function() {_self.yearPanel.open();}
		rows[0][2].onclick = function() {_self.monthPanel.display();}
		zoneMonthPrevious.onclick = function() {
			_self.eventMonthPrevious();
			_self.updateState();
		}
		zoneMonthNext.onclick = function() {
			_self.eventMonthNext();
			_self.updateState();
		}
		
		// css
		table.setAttribute("border", "0");
		table.setAttribute("width", "100%");
		table.setAttribute("cellspacing", "3");
		table.setAttribute("cellpadding", "0");
		zoneYear.className = _self.styleClassYear;
		zoneMonth.className = _self.styleClassMonth;
		zoneYear.style.cssText = zoneMonth.style.cssText = zoneMonthPrevious.style.cssText = zoneMonthNext.style.cssText = "border:0;padding:0;text-align:center;";

		rows[0][0].style.cursor = rows[0][1].style.cursor = rows[0][2].style.cursor = rows[0][3].style.cursor = "pointer";
		this.contentHeader.appendChild(table);
	}
	this.renderBody = function() {
		QFaces.debug("renderBody, date=" + this.getDate());
		var _self = this;
		var date = this.date; 			// 日历面板的日期
		var inputDate = this.loadDate();// 关联的目标组件的日期,并确保不会载入空日期
		if (inputDate == null)
			inputDate = new Date();
		// 当前月的总天数
        var totalDay = QFaces.Faces.UICalendar.Utils.getTotalDaysOfMonth(date.getFullYear(), date.getMonth() + 1);
        // 当前月起始日为星期几?, 起始日为1,必须转换到数组下标，并且避免首日时出现下标越界
        var startDayOfWeek = QFaces.Faces.UICalendar.Utils.getStartDayOfWeek(date.getFullYear(), date.getMonth());

        // render table
        var table = document.createElement("table");
        var rows = QFaces.Utils.createTable(table, 7, 7);
        rows[0][0].innerHTML = this.weekArr[0];
        rows[0][1].innerHTML = this.weekArr[1];
        rows[0][2].innerHTML = this.weekArr[2];
        rows[0][3].innerHTML = this.weekArr[3];
        rows[0][4].innerHTML = this.weekArr[4];
        rows[0][5].innerHTML = this.weekArr[5];
        rows[0][6].innerHTML = this.weekArr[6];
        rows[0][0].className = rows[0][1].className = rows[0][2].className = rows[0][3].className = rows[0][4].className = rows[0][5].className = rows[0][6].className = _self.styleClassWeek;

        // 渲染月份日期
        var rowIndex = 1;   // 第一行为星期Flag
        var colIndex = startDayOfWeek;
        var hasAction = false;
        var highLight = false;
        var currentDay = false;
        var now = new Date();
        for (var i = 0; i < totalDay; i++) {
        	if (this.renderAsPop) {
        		// currentDay 标注今天的日期, hightLight标注选择的日期
        		currentDay = (date.getFullYear() == now.getFullYear() && date.getMonth() == now.getMonth() && (i+1) == now.getDate());
        		highLight = (date.getFullYear() == inputDate.getFullYear() && date.getMonth() == inputDate.getMonth() && (i+1) == inputDate.getDate());
        		rows[rowIndex][colIndex].appendChild(this.renderDayAsSelector(i + 1, _self, highLight, currentDay));        		
        	} else {
        		// currentDay 标注今天的日期, hasAction标注今天是否存在事件
        		currentDay = (date.getFullYear() == now.getFullYear() && date.getMonth() == now.getMonth() && (i+1) == now.getDate());
        		hasAction = this.actionPanel.hasAction(date.getFullYear(), date.getMonth(), i + 1);
        		rows[rowIndex][colIndex].appendChild(this.renderDayAsCalendar(date.getFullYear(), date.getMonth(), (i + 1), _self, hasAction, currentDay));        		
        	}
            colIndex++;
            // 换行
            if (colIndex > 6) {
                colIndex = 0;
                rowIndex++;
            }
        }
        table.className = this.styleClassCalendarBody;
        table.style.cssText = "text-align:center;";
        table.setAttribute("cellspacing", "3"); 
        table.setAttribute("cellpadding", "0");
        table.cellSpacing = 3;
        table.cellPadding = 0;
        while (this.contentBody.hasChildNodes()) {
            this.contentBody.removeChild(this.contentBody.firstChild);
        }
        this.contentBody.appendChild(table);
	}
	this.renderFooter = function() {
		var _self = this;
		var todayZone = document.createElement("div");
		var now = new Date();
		todayZone.innerHTML = "Today：" + now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
		todayZone.style.cssText = "border:0;width:120px;margin:auto;";
		if (_self.renderAsPop) {
			todayZone.style.cursor = "pointer";
			todayZone.onmouseover = function() {
				this.className = _self.styleClassDayOnmouseover;
			}
			todayZone.onmouseout = function() {
				this.className = "";
			}
			todayZone.onclick = function() {
				_self.setDate(new Date(), true);
				if (_self.autoClose) _self.close();
			}
		}
		this.contentFooter.appendChild(todayZone);
	}
	// 渲染月份中的某一天(事件日历)
	this.renderDayAsCalendar = function(year, month, dayOfMonth, calendar, hasAction, currentDay) {
		var obj = document.createElement("div");
		if (hasAction) {
			var link = document.createElement("a");
			var dayZone = document.createElement("div");
			link.setAttribute("href", calendar.href + "?year=" + year + "&month=" + month + "&day=" + dayOfMonth);
			link.setAttribute("target", calendar.target);
			dayZone.innerHTML = dayOfMonth;
			dayZone.className = calendar.styleClassActionDate;
			// 如果客户端设定了不显示actionPanel,则这里将不响应
			if (calendar.showActionPanel) {
				dayZone.onmouseover = function() {
					this.className = calendar.styleClassDayOnmouseover;
					obj.appendChild(calendar.actionPanel.getPanel(calendar.date.getFullYear(), calendar.date.getMonth(), dayOfMonth));
				}
				dayZone.onmouseout = function() {
					this.className = calendar.styleClassActionDate;
					calendar.actionPanel.close();
				}				
			}
			link.appendChild(dayZone);
			obj.appendChild(link);
		} else {
			obj.innerHTML = dayOfMonth;
			obj.className = currentDay ? calendar.styleClassDayCurrent : calendar.styleClassDayOfMonth;
		}
		
		return obj;
	}
	// 渲染月份中的某一天(日期选择器)
	this.renderDayAsSelector = function(day, calendar, highLight, currentDay) {
		var obj = document.createElement("div");
		obj.value = day;
		obj.innerHTML = day;
		obj.style.cursor = "pointer";
		obj.className = currentDay ? calendar.styleClassDayCurrent : calendar.styleClassDayOfMonth;
		if (highLight) {
			obj.className = calendar.styleClassDaySelected;
		} else {
			obj.onmouseover = function() {
				this.className = calendar.styleClassDayOnmouseover;
			}
			obj.onmouseout = function() {
				var now = new Date();
				if (calendar.date.getFullYear() == now.getFullYear() && calendar.date.getMonth() == now.getMonth() && this.value == now.getDate()) {
					this.className = calendar.styleClassDayCurrent;
				} else {
					this.className = calendar.styleClassDayOfMonth;
				}
			}
		}
		// 日历的点击事件
		obj.onclick = function() {calendar.eventDateSelect(this.value);}
		return obj;
	}
	// 从关联的组件中读取日期字串，并转化为js Date类型
	this.loadDate = function() {
		QFaces.debug("loadDate...");
		var _dd = null;
		if (this.input != null)
			_dd = QFaces.DateFormat.parse(this.input.value, this.pattern);
		if (_dd == null && this._for != null && this._for.length > 0) {
			for (var i = 0; i < this._for.length; i++) {
				var forObj = QFaces.Utils.getElement(this._for[i]);
				if (forObj != null && forObj.value != null) {
					_dd = QFaces.DateFormat.parse(forObj.value, this.pattern);
					if (_dd != null) break;
				}
			}
		}
		return _dd;
	}
	// 更新日期并重新渲染日历面板,updateTarget参数定义是否立即更新目标组件的值
	this.updateState = function(updateTarget) {
		QFaces.debug("updateState,date=" + this.date);
		// 重新显示年份月份
		this.objYear.innerHTML = this.date.getFullYear();
		this.objMonth.innerHTML =  this.monthArr[this.date.getMonth()];
		// 更新目标组件的值(更新目标组件的值必须在“重新渲染主区域之前，因为renderBody中会检测到目标组件的值”)
		if (updateTarget) this.updateTargetValue();
		// 重新渲染日期主区域
		this.renderBody();
	}
	// 关于年份与月份的选择，如果组件运行模式非日期选择期（renderAsPop)则需要到后台查询存在活动事件的日期
	this.eventSetYear = function(year) {
		this.date.setFullYear(year, this.date.getMonth(), 1);
		if (!this.renderAsPop) {
			this.ajaxInvokeActionDate();
		}
	}
	this.eventSetMonth = function(month) {
		this.date.setMonth(month, 1);
		if (!this.renderAsPop) {
			this.ajaxInvokeActionDate();
		}
	}
	this.eventMonthPrevious = function() {
		this.date.setDate(1);
		this.date.setMonth(this.date.getMonth() - 1);
		if (!this.renderAsPop) {
			this.ajaxInvokeActionDate();
		}
	}
	this.eventMonthNext = function() {
		// setDate(1)用于防止月份跳转出错，比如当前为3月31日，那么设置月份加1之后变成yyyy-4-31,
        // 因为4月没有31日, 所以日期会被转换到5月1日.这会导致界面显示的日期突然从3变成5月
        this.date.setDate(1);
        this.date.setMonth(this.date.getMonth() + 1);
        if (!this.renderAsPop) {
			this.ajaxInvokeActionDate();
		}
	}
	// 当用户选择某一天之后的影响事件
	this.eventDateSelect = function(dateOfMonth) {
		var now = new Date();
		// 除了设定所选择的日期之外，还应该同步时间
		this.date.setDate(dateOfMonth);
		this.date.setHours(now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds())
		this.setDate(this.date, true); // 直接由setDate方法去更新所有状态
		if (this.autoClose) this.close();
	}
	// 更新目标组件的值
	this.updateTargetValue = function() {
		var strDate = QFaces.DateFormat.format(this.date, this.pattern);
		// 设置目标组件的值
		if (this.input != null)
			this.input.value = strDate;
		if (this._for != null) {
			for (var i = 0; i < this._for.length; i++) {
				var obj = QFaces.Utils.getElement(this._for[i]);
				if (obj != null) obj.value = strDate;
			}
		}
	}
	// Ajax Invoke, 从后台获取当前选中年份，月份的活动日期列表
	this.ajaxInvokeActionDate = function(calendar) {
		var _self = (calendar ? calendar : this);
		// 用户可能未绑定方法,所以直接返回
		if (_self.listenerExp == "")
			return;
		QFaces.debug("Ajax invoke start...");        
        QFaces.Faces.Messenger.processing(true);
        var ajax = QFaces.Faces.Ajax.getAjax(_self.ID_CLIENT);
        ajax.put("componentClass", _self.componentClass);
        ajax.put("listenerExp", _self.listenerExp);
        ajax.put("year", _self.date.getFullYear());
        ajax.put("month", _self.date.getMonth());
        var processWhenOK = function() {
        	QFaces.Faces.Messenger.processing(false);
        	var year = _self.date.getFullYear();
        	var month = _self.date.getMonth();
        	var xml = ajax.request.responseXML;
        	if (!xml) return;
        	var dayNodes = xml.documentElement.getElementsByTagName("day");
        	if (dayNodes.length <= 0) return;
        	var actionDates = new Array(dayNodes.length);
        	for (var i = 0; i < dayNodes.length; i++) {
        		var temp = dayNodes[i];
        		actionDates[i] = new QFaces.Faces.UICalendar.ActionDate(temp.getAttribute("dayOfMonth"), temp.getAttribute("description"));
        		QFaces.debug("生成actionDate=" + actionDates[i].toString());
        	}
        	// 载入“事件日期”
        	_self.actionPanel.load(year, month, actionDates);
        	// 重置,确保日期正确,然后重新渲染
        	_self.date.setMonth(month);
        	_self.date.setYear(year);
        	_self.updateState();
        }
        ajax.setProcess(processWhenOK);
        ajax.get();
	}
	this.isOpen = function() {return (this.frame.style.display != "none");}
	// 初始化
	this.init();
}
QFaces.Faces.UICalendar.ActionDate = function (dayOfMonth, description) {
	this.dayOfMonth = dayOfMonth;
	this.description = description;
	this.toString = function() {
		return "[" + this.dayOfMonth + ", " + this.description + "]";
	}
}
QFaces.Faces.UICalendar.ActionPanel = function(calendar) {
	this.calendar = calendar;
	this.panel = null;
	this.year = null;
	this.month = null;
	this.actionDates = null;
	
	this.init = function() {
		var _self = this;
		this.panel = document.createElement("div");
		this.panel.className = this.calendar.styleClassActionPanel;
		this.panel.style.position = "absolute";
		this.panel.onmouseover = function() {
			_self.open();
		}
		this.panel.onmouseout = function() {
			_self.close();
		}
	}
	this.load = function(year, month, actionDates) {
		this.year = year;
		this.month = month;
		this.actionDates = new Array(actionDates.length);
		for (var i = 0; i < actionDates.length; i++) {
			var ad = actionDates[i];
			this.actionDates[this.genKey(this.year, this.month, ad.dayOfMonth)] = ad;
		}
	}
	this.hasAction = function(y, m, d) {
		return (this.actionDates != null && this.actionDates[this.genKey(y, m, d)] != null);
	}
	this.getAction = function(y, m, d) {
		if (this.hasAction(y, m, d)) 
			return this.actionDates[this.genKey(y, m, d)];
		return null;
	}
	this.getPanel = function(y, m, d) {
		var ad = this.getAction(y, m, d);
		if (ad != null)
			this.panel.innerHTML = ad.description;
		this.open();
		return this.panel;
	}
	this.genKey = function(y, m, d) {return (y + "-" + m + "-" + d);}	
	this.display = function() {QFaces.Utils.display(this.panel);}
	this.open = function() {QFaces.Utils.open(this.panel);}
	this.close = function() {QFaces.Utils.close(this.panel);}
	this.init();
}

QFaces.Faces.UICalendar.YearPanel = function(calendar) {
	this.calendar = calendar;
	this.panel;
	this.yearZones;
	this.scrolling = false;	// 用于控制年份的滚动
	
	this.init = function() {
		var _self = this;
		this.panel = document.createElement("div");
		this.yearZones = new Array(_self.calendar.visibleYear);
		
		// 生成年份选择区域及滚动按钮区域
		var zoneYearPrevious = document.createElement("div");
		var zoneYearNext = document.createElement("div");
		for (var i = 0; i < _self.calendar.visibleYear; i++)
			this.yearZones[i] = document.createElement("div");
		
		// 将各个选项添加到panel中
		this.panel.appendChild(zoneYearPrevious);
		for (var i = 0; i < this.yearZones.length; i++)
			this.panel.appendChild(this.yearZones[i]);
		this.panel.appendChild(zoneYearNext);
		
		// 载入数据
		zoneYearPrevious.innerHTML = " - ";
		zoneYearNext.innerHTML = " + ";
		this.reload(_self.calendar.startYear);
		
		// 设置JS Event
		this.setEventCss(zoneYearPrevious);
		this.setEventCss(zoneYearNext);
		for (var i = 0; i < this.yearZones.length; i++) {
			this.setEventCss(this.yearZones[i]);
			this.setEventSelect(this.yearZones[i], _self);
		}
		zoneYearPrevious.onmousedown = function() {
			_self.scrolling = true;
			_self.scrollEvent(_self, false);
		}
		zoneYearNext.onmousedown = function() {
			_self.scrolling = true;
			_self.scrollEvent(_self, true);
		}
		zoneYearPrevious.onmouseup = zoneYearPrevious.onmouseout = function() {_self.scrolling = false;}
		zoneYearNext.onmouseup = zoneYearNext.onmouseout = function() {_self.scrolling = false;}
		this.panel.onmouseover = function() {_self.open();}
		this.panel.onmouseout = function() {_self.close();}
		
		// 更新选择状态
		this.updateState();
		
		// 设置基本样式
		this.panel.style.cssText = "position:absolute;border:2px solid #C0C0C0;background:#FFF;text-align:center;min-width:50px;margin:0 0 0 -1px;";
		zoneYearNext.style.background = zoneYearPrevious.style.background = "#C0C0C0";
		
		// 初始状态为隐藏的
		this.close();
	}
	// 重新载入选择列表,从startYear开始
	this.reload = function(startYear) {
		for (var i = 0; i < this.yearZones.length; i++) {
			this.yearZones[i].value = startYear + i;
			this.yearZones[i].innerHTML = startYear + i;
		}
	}
	// 更新“选中”状态,将列表中与calendar中相同的年份高显示
	this.updateState = function() {
		for (var i = 0; i < this.yearZones.length; i++) {
			this.setSelectCss(this.yearZones[i], (this.yearZones[i].value == this.calendar.getDate().getFullYear()))
		}
	}
	this.scrollEvent = function(_self, add) {
		for (var i = 0; i < _self.yearZones.length; i++) {
			var yearSel = _self.yearZones[i];
			yearSel.value = add ? (yearSel.value + 1) : (yearSel.value - 1);
			yearSel.innerHTML = yearSel.value;
			// 在滚动年份的时候需要判断是否为当前年份，以改变样式
			_self.setSelectCss(yearSel, (yearSel.value == _self.calendar.getDate().getFullYear()));
		}
		if (_self.scrolling) {
			QFaces.Utils.setTimeout(_self.scrollEvent, 10, _self, add);			
		}
	}
	// 设置年份列表的事件触发
	this.setEventSelect = function(obj, _self) {
		obj.onclick = function() {
			_self.calendar.eventSetYear(this.value);
			_self.calendar.updateState();
			_self.updateState();
		}
	}
	this.setEventCss = function(obj) {
		obj.style.padding = "0 10px";
		obj.style.borderBottom = "1px dotted gray";
		obj.onmouseover = function() {
			this.style.background = "#C0C0C0";
		}
		obj.onmouseout = function() {
			this.style.background = "";
		}
	}
	// 设置被选中的年份的样式
	this.setSelectCss = function(obj, selected) {obj.className = selected ? this.calendar.styleClassYearSelected : "";}
	this.getPanel = function() {return this.panel;}
	this.display = function() {this.panel.style.display == "none" ? this.open() : this.close();}
	this.open = function() {
		QFaces.Utils.open(this.panel);
		this.updateState();
	}
	this.close = function() {
		QFaces.Utils.close(this.panel);
	}
	this.init();
}
QFaces.Faces.UICalendar.MonthPanel = function(calendar) {
	this.calendar = calendar;
	this.panel;
	this.monthZones;
	
	this.init = function() {
		this.panel = document.createElement("div");
		this.monthZones = new Array(12);
		for (var i = 0; i < 12; i++) {
			var month = document.createElement("div");
			month.value = i;	// 必须的，用于保存月份的数值
			month.innerHTML = this.calendar.monthArr[i];
			this.setEventCss(month);
			this.setEventSelect(month, this.calendar);
			this.panel.appendChild(month);
			this.monthZones[i] = month;
		}
		var _self = this;
		this.panel.style.cssText = "position:absolute;border:2px solid #C0C0C0;background:#FFF;text-align:center;min-width:50px;margin:0 0 0 -1px;";
		this.panel.onmouseover = function() {_self.open();}
		this.panel.onmouseout = function() {_self.close();}
		this.close();
	}
	this.setEventSelect = function(obj, calendar) {
		obj.onclick = function() {
			calendar.eventSetMonth(this.value);
			calendar.updateState();
		}
	}
	this.setEventCss = function(obj) {
		obj.style.cssText = "padding:0 3px;border-bottom:1px dotted gray";
		obj.onmouseover = function() {
			this.style.background = "#C0C0C0";
		}
		obj.onmouseout = function() {
			this.style.background = "";
		}
	}
	// 设置被选中的月份的样式
	this.setSelectCss = function(obj, selected) {obj.className = selected ? this.calendar.styleClassMonthSelected : "";}
	this.getPanel = function() {return this.panel;}
	this.display = function() {this.panel.style.display == "none" ? this.open() : this.close();}
	this.open = function() {
		QFaces.Utils.open(this.panel);
		this.updateState();
	}
	this.close = function() {this.panel.style.display = "none";}
	this.updateState = function() {
		for (var i = 0; i < this.monthZones.length; i++) {this.setSelectCss(this.monthZones[i], (this.monthZones[i].value == this.calendar.getDate().getMonth()));}
	}
	this.init();
}

